#!/usr/bin/python3

1. 内置的open函数打开文件有几种模式，它们的区别是什么？
r：只读打开，文件指针位于文件的开头。如果文件不存在，就会报FileNotFoundError异常。

w：只写打开，如果文件存在，就会清空文件内容，如果文件不存在，就创建一个新文件。

x：创建并写入一个新文件，如果文件存在，打开失败并抛出FileExisError异常。

a：只写打开，追加内容，如果文件不存在，就创建一个新文件。

b：二进制模式，以二进制方式打开文件，用于处理非文本文件，如图片、音频等。

t：缺省模式，文本模式，以文本方式打开文件。

+：读或写打开后，使用+来增加缺失的写或读的能力


2. 使用base64解码“bWFnZWR1LmNvbQ==”，使用base64编码”[magedu.com](http://magedu.com)”，分别给出它们的解码和编码结果。
import base64

str1="bWFnZWR1LmNvbQ=="
bytes1=base64.b64decode(str1)
print("结果: {}".format(bytes1.decode('utf-8')))

tr2="[magedu.com](http://magedu.com)"
bytes2=base64.b64encode(str2.encode('utf-8'))
print("编码结果：{}".format(bytes2.decode('utf-8')))

3. 列出本周讲的几种序列化方法，它们各自的特点是什么?

一、pickle：Python标准库提供的序列化方法。能够序列化几乎所有的Python对象，包括自定义的类。支持复杂的数据结构。缺点：pickle格式是Python特有的，不适用于与其他语言交互。安全性问题，不建议对不信任的数据进行反序列化，容易受到代码注入攻击。

import pickle
filename='text.txt'

i=99
c='c'
l=list('123')
d={'a':127,'b':'abc','c':[1,2,3]}

with open(filename,'wb') as f:
    pickle.dump(i,f)
    pickle.dump(c,f)
    pickle.dump(l,f)
    pickle.dump(d,f)

with open(filename,'rb') as f:
    print(f.read(),f.seek(0))
    for i in range(4):
        x=pickle.load(f)
        print(i,x,type(x))



二、json：文本格式，轻量级的数据交换格式。易于人阅读和编写，同时也易于机器解析和生成。主要用于Web领域应用中的数据传输。缺点：不能序列化所有类型的Python对象，如函数、类实例等。仅支持基本数据类型：字符串、数值、列表、字典等。

import json
d={'name':'tom','age':20,'interest':('music','movie'),'class':['python']}
j=json.dumps(d)
print(j,type(j))

d1=json.loads(j)
print(type(d1),d1)
#print(d==d1)
#print(d is d1


三：MessagePack：一种二进制格式的序列化方法。结合了JSON的简洁性和pickle的效率。适合于高效率的数据存储或网络传输。缺点：不如JSON可读，二进制格式使得其难以直接编辑。

pip3 install msgpack

import pickle
import json
import msgpack

methods = (pickle,json,msgpack)
d = {'person':[{'name':'tom','age':18},{'name':'jerry','age':16}],'total':2}

for m in methods:
    s = m.dumps(d)
    print(m.__name__,type(s),len(s),s)

print('-'*30)


u = msgpack.loads(s)
print(type(u),u)

u2=msgpack.loads(s,raw=False)
print(type(u2),u2)



4. 写一个Python脚本实现找到/tmp目录及其子目录下的以.htm结尾的文件，把其后缀名改为.html

方法一：字符串拼接方式
import os

def renamefile_to_html(directory):
    for root,dirs,files in os.walk(directory):
        for f in files:
            if f.endswith('.htm'):
                origin_file = os.path.join(root,f)
                new_file = os.path.join(root,f[:-4]+'.html')

                os.rename(origin_file,new_file)
                print('rename {} to {} '.format(origin_file,new_file))

dirs='/tmp'
renamefile_to_html(dirs)


方法二：操作Path对象通配符递归方式
import shutil
from pathlib import Path

def renamefile_to_html(directory):
    for f in list(directory.rglob('*.htm')):
        new_file=f.with_suffix('.html')
        shutil.move(f,new_file)
        print("rename {} to {} ".format(f,new_file))

dirs=Path('/tmp')
renamefile_to_html(dirs)
